package com.lzhl.buildjar.dao;

import com.lzhl.buildjar.dao.update.UpdateManager;
import com.lzhl.buildjar.exception.DaoException;
import com.lzhl.buildjar.util.DbUtils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Dao工厂
 * @author 李柱良(@柱子的日月)
 * @date 2014/6/18
 */
public class DaoFactory {
    private static Map<String, Dao> daos = new HashMap<String, Dao>();
    private static Connection connection = null;

    private static Properties names = new Properties();
    private static Properties props = new Properties();

    static {
        InputStream daoInputStream = null;
        InputStream dbInputStream = null;

        try {
            daoInputStream = DaoFactory.class.getResourceAsStream("/dao.properties");
            names.load(daoInputStream);

            dbInputStream = DaoFactory.class.getResourceAsStream("/db.properties");
            props.load(dbInputStream);
        }
        catch (IOException e) {
            throw new DaoException(e);
        }
        finally {
            if(daoInputStream != null) {
                try {
                    daoInputStream.close();
                } catch (IOException ignore) {
                }
            }
            if(dbInputStream != null) {
                try {
                    dbInputStream.close();
                } catch (IOException ignore) {
                }
            }
        }
    }

    private static Connection getConnection() {
        if(connection == null) {
            connection = DbUtils.getConnection(props);
            try {
                UpdateManager manager = new UpdateManager();
                manager.setConnection(connection);
                manager.update();
            }
            catch (SQLException e) {
                throw new DaoException("数据库升级失败！", e);
            }

        }
        return connection;
    }

    public static void close() {
        if(connection != null) {
            try {
                connection.close();
                connection = null;
            } catch (SQLException e) {
                connection = null;
                e.printStackTrace();
            }
        }
    }

    public synchronized static Dao getDao(String name) {
        if(name == null) {
            return null;
        }

        if(daos.containsKey(name)) {
            return daos.get(name);
        }

        String clazzName = names.getProperty(name);
        if(clazzName == null || clazzName.trim().length() == 0) {
            throw new DaoException("Dao:["+ name +"]定义有误。");
        }

        try {
            clazzName = clazzName.trim();
            Class clazz = Class.forName(clazzName);
            Dao dao = (Dao) clazz.newInstance();
            dao.setConnection(getConnection());
            daos.put(name, dao);

            return dao;
        } catch (ClassNotFoundException e) {
            throw new DaoException("Dao:["+ clazzName +"]类未找到。", e);
        } catch (InstantiationException e) {
            throw new DaoException("Dao:["+ clazzName +"]无法初始化。", e);
        } catch (IllegalAccessException e) {
            throw new DaoException("Dao:["+ clazzName +"]无法初始化。", e);
        }
    }

    public static CategoryDao getCategoryDao() {
        return (CategoryDao) DaoFactory.getDao("categoryDao");
    }

    public static SchemeDao getSchemeDao() {
        return (SchemeDao) DaoFactory.getDao("schemeDao");
    }

    public static SettingDao getSettingDao() {
        return (SettingDao) DaoFactory.getDao("settingDao");
    }

    public static void main(String[] args) {
        System.out.println(getConnection());
    }

}
